package com.ksyun.campus.metaserver.services;

import com.ksyun.campus.metaserver.domain.BlockInfo;
import com.ksyun.campus.metaserver.domain.Inode;
import com.ksyun.campus.metaserver.domain.StatInfo;

import java.util.List;

/**
 * MetaServer 核心服务接口
 * 定义了分布式文件系统的核心操作，包括文件系统初始化、目录和文件操作、块分配等
 * 该接口是MetaServer对外提供服务的主要入口
 */
public interface IMetaService {
    
    /**
     * 初始化文件系统
     * 创建根目录并设置集群配置信息
     * 该方法在MetaServer启动时调用
     */
    void initializeFileSystem() throws Exception;
    
    /**
     * 递归创建目录
     * 如果路径中的父目录不存在，会自动创建
     * 
     * @param path 目录路径，必须以'/'开头的绝对路径
     * @param permissions 目录权限，如755表示所有者可读写执行，组和其他用户可读执行
     * @param owner 所有者用户名
     * @param group 所有者组名
     * @return 创建的目录inode对象
     * @throws Exception 如果路径已存在且为文件，或创建过程中发生错误
     */
    Inode mkdirs(String path, int permissions, String owner, String group) throws Exception;
    
    /**
     * 创建文件
     * 创建一个空文件，不包含任何数据块
     * 
     * @param path 文件路径，必须以'/'开头的绝对路径
     * @param replication 副本数，指定文件数据块的副本数量
     * @param permissions 文件权限，如644表示所有者可读写，组和其他用户可读
     * @param owner 所有者用户名
     * @param group 所有者组名
     * @return 创建的文件inode对象
     * @throws Exception 如果路径已存在，或父目录不存在，或创建过程中发生错误
     */
    Inode createFile(String path, int replication, int permissions, String owner, String group) throws Exception;
    
    /**
     * 删除文件或目录
     * 
     * @param path 要删除的文件或目录路径
     * @param recursive 是否递归删除，如果为false且目录非空，则会抛出异常
     * @throws Exception 如果路径不存在，或目录非空且recursive=false，或删除过程中发生错误
     */
    void delete(String path, boolean recursive) throws Exception;
    
    /**
     * 获取文件/目录状态
     * 
     * @param path 文件或目录路径
     * @return 状态信息对象，包含文件类型、大小、权限、时间戳等信息
     * @throws Exception 如果路径不存在或获取状态过程中发生错误
     */
    StatInfo getStatus(String path) throws Exception;
    
    /**
     * 列出目录内容
     * 
     * @param path 目录路径
     * @return 目录下所有文件和子目录的状态信息列表
     * @throws Exception 如果路径不存在，或不是目录，或列出过程中发生错误
     */
    List<StatInfo> listStatus(String path) throws Exception;
    
    /**
     * 获取文件的块信息
     * 
     * @param fileId 文件ID，通过路径解析或其他方式获取
     * @return 文件的所有数据块信息列表
     * @throws Exception 如果文件不存在或获取块信息过程中发生错误
     */
    List<BlockInfo> getFileBlocks(String fileId) throws Exception;
    
    /**
     * 为文件分配块
     * 根据请求的字节数计算需要分配的块数量，并为每个块选择合适的DataServer
     * 
     * @param fileId 文件ID
     * @param bytes 需要的字节数，用于计算需要分配多少个块
     * @return 分配的块信息列表，包含块索引和副本位置信息
     * @throws Exception 如果文件不存在，或没有足够的DataServer，或分配过程中发生错误
     */
    List<BlockInfo> allocateBlocks(String fileId, long bytes) throws Exception;
    
    /**
     * 提交文件写入
     * 更新文件的大小、修改时间和校验和信息
     * 
     * @param fileId 文件ID
     * @param size 文件最终大小
     * @param blocks 写入的块信息列表，包含每个块的实际大小
     * @param checksum 文件校验和，用于数据完整性验证
     * @throws Exception 如果文件不存在或提交过程中发生错误
     */
    void commitWrite(String fileId, long size, List<BlockInfo> blocks, String checksum) throws Exception;
    
    /**
     * 解析路径获取文件ID
     * 将文件路径转换为内部的文件唯一标识符
     * 
     * @param path 文件路径
     * @return 文件的内部ID
     * @throws Exception 如果路径不存在或解析过程中发生错误
     */
    String resolvePathToFileId(String path) throws Exception;
}
